/* The Link = http://poj.org/problem?id=1095
 * The initial thinking is to use the binary representation of one integer, 
 * But then I found myself to be wrong. I don't know about the catalan(may be spelled wrong)
 *, so I find the scheme between the number of trees and the number of vertices. Then PRINT the trees iteratively
 */

#include <iostream>

using namespace std;

// 100 is an estimated value
const int MAX_NUMBER_OF_VERTICES = 101;
unsigned long numberOfTreesPerVertex[MAX_NUMBER_OF_VERTICES] = {0};
int currentNumber = 0;

int getNumberOfTreesFromVertices(int numberOfVertices)
{
	if (numberOfVertices == 1)
	{
		numberOfTreesPerVertex[numberOfVertices] = 1;
		currentNumber = numberOfVertices;
		return 1;
	}

	if (numberOfVertices > currentNumber) {
		for (int i = currentNumber + 1; i < numberOfVertices + 1; i++) {
			unsigned long count = numberOfTreesPerVertex[i - 1] * 2;
			for (int j = 1; j < i - 1; j++) {
				count += numberOfTreesPerVertex[j] * numberOfTreesPerVertex[i - 1 - j];
			}
			numberOfTreesPerVertex[i] = count;
		}
		currentNumber = numberOfVertices;
	}


	return numberOfTreesPerVertex[numberOfVertices];
}

int getNumberOfVertices( int n, int &remainPosition) 
{
	int numberOfVertices = 1;
	while (n > 0) {
		remainPosition = n;
		n -= getNumberOfTreesFromVertices(numberOfVertices);
		numberOfVertices++;
	}
	
	return --numberOfVertices;
}

//int getLeftAndRightTreeNumber(int n, int remainPosition) 
//{
//	int left, right;
//	if (remainPosition <= n - 1)
//	{
//		left = 0;
//		right = n - 1;
//		return left;
//	}
//	remainPosition -= n - 1;
//	int leftRemainPosition = -1, rightRemainPosition;
//	for (int j = 1; j < n - 1; j++) {
//		int interm = numberOfTreesPerVertex[j] * numberOfTreesPerVertex[n - 1 - j];
//		if (remainPosition <= interm) {
//			left = j;
//			leftRemainPosition = -1;
//			right = n - 1 - j;
//			while (remainPosition > 0) {
//				++leftRemainPosition;
//				rightRemainPosition = remainPosition;
//				remainPosition -= numberOfTreesPerVertex[right];
//			}
//			break;
//		}
//		remainPosition -= interm;
//	}
//}

void printfTree(int n, int remainPosition) 
{
	if (n == 1)
	{
		printf("X");
		return;
	}	
	if (remainPosition <= numberOfTreesPerVertex[n - 1])
	{
		printf("X(");
		printfTree(n - 1, remainPosition);
		printf(")");
		return;
	}
	int left, right;
	remainPosition -= numberOfTreesPerVertex[n - 1];
	int leftRemainPosition = 0, rightRemainPosition;
	for (int j = 1; j < n - 1; j++) {
		int interm = numberOfTreesPerVertex[j] * numberOfTreesPerVertex[n - 1 - j];
		if (remainPosition <= interm) {
			left = j;
			leftRemainPosition = 0;
			right = n - 1 - j;
			while (remainPosition > 0) {
				++leftRemainPosition;
				rightRemainPosition = remainPosition;
				remainPosition -= numberOfTreesPerVertex[right];
			}
			break;
		}
		remainPosition -= interm;
	}

	if (leftRemainPosition == 0) {
		printf("(");
		printfTree(n - 1, remainPosition);
		printf(")X");
	} else {
		printf("(");
		printfTree(left, leftRemainPosition);
		printf(")X(");
		printfTree(right, rightRemainPosition);
		printf(")");
	}
}

int main(int argc, char *argv[])
{
	int n;
	while (cin >> n && n != 0) {
		int remainPosition;
		int num = getNumberOfVertices(n, remainPosition);
		printfTree(num, remainPosition);
		printf("\n");
	}
	
	return 0;
}